﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web;
using System.Xml;
using System.IO;
using System.Linq;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;
using Lswweb.Model;
using Lswweb.Common;
using Lswweb.Domain.ResourceConfiguration;

namespace Lswweb.Domain
{
    /// <summary>
    /// 站点url控制
    /// </summary>
    public partial class SiteUrls
    {
        private ResourceUrls siteUrls;
        private ICollection<ReWrittenUrl> reWrittenUrls;

        public SiteUrls(ResourceUrls urls)
        {
            this.siteUrls = urls;
            this.reWrittenUrls = null;
        }

        #region static methods

        private static SiteUrls urls;
        public static SiteUrls Urls
        {
            get
            {
                if (urls == null)
                    urls = new SiteUrls(ResourceManagement.UrlCollection);

                return urls;
            }
        }

        /// <summary>
        /// 此方法需要改进，
        /// </summary>
        /// <param name="urlStr"></param>
        /// <returns></returns>
        public static ReWrittenUrl GetRewriteUrl(string urlStr)
        {
            foreach (ReWrittenUrl rewriter in SiteUrls.Urls.ReWrittenUrls)
            {
                if (rewriter.IsMatch(urlStr))
                    return rewriter;
            }

            return null;
        }

        #endregion

        public ResourceUrls ResourceUrls
        {
            get { return this.siteUrls; }
        }

        public ICollection<ReWrittenUrl> ReWrittenUrls
        {
            get
            {
                if (reWrittenUrls == null)
                {
                    reWrittenUrls = new List<ReWrittenUrl>();

                    foreach (KeyValuePair<string, Url> url in this.siteUrls)
                    {
                        if (url.Value.UrlRewrite != null)
                            this.reWrittenUrls.Add(url.Value.UrlRewrite);
                    }
                }

                return this.reWrittenUrls;
            }
        }

        #region 全局Url

        public string Home
        {
            get { return this.siteUrls["Home"].ToString(); }
        }

        public string AdminHome
        {
            get { return this.siteUrls["admin_Home"].ToString(); }
        }

        public string Login
        {
            get { return this.siteUrls["login"].ToString(); }
        }

        public string SignOut
        {
            get { return this.siteUrls["signOut"].ToString(); }
        }

        /// <summary>
        /// 获取根据模块删除资料的网址
        /// </summary>
        /// <param name="id">信息id</param>
        /// <param name="type">信息所属模块</param>
        /// <param name="isTrue">是否为物理删除</param>
        /// <returns>删除记录网址</returns>
        public string Deleted(string id, SiteModule type, bool isTrue)
        {
            return this.siteUrls["deleted"].BuilderUrl(id,(int)type,isTrue);
        }

        public string IsTop(string id, SiteModule type, bool isTrue)
        {
            return this.siteUrls["isTop"].BuilderUrl(id, (int)type, isTrue);
        }

        public string IsHot(string id, SiteModule type, bool isTrue)
        {
            return this.siteUrls["isHot"].BuilderUrl(id, (int)type, isTrue);
        }

        public string Status(string id, SiteModule type, int status)
        {
            return this.siteUrls["status"].BuilderUrl(id, (int)type, status);
        }

        public string FileDownload(string fileUrl)
        {
            if (string.IsNullOrEmpty(fileUrl))
                return string.Empty;

            return this.siteUrls["fileDownload"].BuilderUrl(fileUrl);
        }

        #endregion

        #region Users

        /// <summary>
        /// 编辑会员资料
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public string UserEdit(int userId)
        {
            return this.siteUrls["admin_UserEdit"].BuilderUrl(userId);
        }

        public string UserChangePassword(int userId)
        {
            return this.siteUrls["admin_UserChangePsw"].BuilderUrl(userId);
        }

        public string UserMyself()
        {
            return this.siteUrls["userMySelf"].ToString();
        }

        public string UserRegister()
        {
            return this.siteUrls["userRegister"].ToString();
        }

        public string UserLogin()
        {
            return this.siteUrls["userLogin"].ToString();
        }

        public string UserGetPassword()
        {
            return this.siteUrls["userGetPassword"].ToString();
        }

        public string UserChangePassword()
        {
            return "#";
        }

        public string UserAdminPowers(int userId)
        {
            return "#";
        }

        public string UserProfileEdit(int userId)
        {
            return this.siteUrls["userProfileEdit"].BuilderUrl(userId);
        }

        public string UserChangePsw(int userId)
        {
            return this.siteUrls["userChangePsw"].BuilderUrl(userId);
        }

        public string MyOrder(int userId, OrderStatus state)
        {
            return this.siteUrls["myOrder"].BuilderUrl(userId, (int)state);
        }
        public string MyOrder(int userId)
        {
            return MyOrder(userId, (OrderStatus)(-1));
        }

        public string MyCommentary(int userId)
        {
            return this.siteUrls["myCommentary"].BuilderUrl(-1);
        }
        #endregion

        #region News

        public string NewsEdit(int newsId, int baseNodeId)
        {
            return this.siteUrls["admin_NewsEdit"].BuilderUrl(baseNodeId, newsId);
        }

        public string NewsAdd()
        {
            return this.siteUrls["admin_NewsAdd"].ToString();
        }

        public string NewsSearch(object obj)
        {
            CategoryInfo category = obj as CategoryInfo;
            if (category == null)
                return string.Empty;

            int baseNodeId = TreeTables.NewsCategories.GetBaseNode(category.Id).Id;
            return this.NewsSearch(baseNodeId, category.Id, string.Empty);
        }
        public string NewsSearch(int baseNodeId, int categoryId, string searchKey)
        {
            return this.siteUrls["news"].BuilderUrl(baseNodeId, categoryId, searchKey);
        }

        public string NewsSearchAdmin(bool enableDelBtn, bool enableTopBtn, bool enableHotBtn, int baseNodeId, int categoryId, string searchKey)
        {
            return this.siteUrls["admin_NewsList"].BuilderUrl(enableDelBtn, enableTopBtn, enableHotBtn, baseNodeId, categoryId, searchKey);
        }


        public string NewsShow(object arg)
        {
            NewsInfo info = arg as NewsInfo;
            if (info == null || info.NewsId==0)
                return string.Empty;

            int baseNodeId=SiteContext.Current.BaseNodeId;
            if (baseNodeId == -1)
            {
                CategoryInfo baseNode=TreeTables.NewsCategories.GetBaseNode(info.NewsCategoryId);
                if (baseNode != null)
                    baseNodeId = baseNode.Id;
                else
                    return string.Empty;
            }

            return this.NewsShow(
                baseNodeId, 
                info.NewsCategoryId, 
                info.NewsId);
        }
        public string NewsShow(int baseNodeId, int categoryId, int newsId)
        {
            return this.siteUrls["newsShow"].BuilderUrl(baseNodeId, categoryId, newsId);
        }

        public string AboutUs(object arg)
        {
            NewsInfo info = arg as NewsInfo;
            if (info == null)
                return string.Empty;

            return this.siteUrls["aboutUs"].BuilderUrl(info.NewsCategoryId, info.NewsId);
        }
        public string AboutUs(int categoryId, int id)
        {
            return this.siteUrls["aboutUs"].BuilderUrl(categoryId, id);
        }

        public string FAQ(object arg)
        {
            NewsInfo info = arg as NewsInfo;
            if (info == null)
                return string.Empty;

            return FAQ(SiteContext.Current.BaseNodeId, info.NewsId);
        }
        public string FAQ(int baseNodeId, int id)
        {
            NewsInfo news = News.GetNews(id);

            return this.siteUrls["faq"].BuilderUrl(
                baseNodeId,
                id,
                news == null ? "Faq" : this.UrlEncode(news.Title));
        }
        #endregion\

        #region Products

        public string ProductCategoryShow(object arg)
        {
            CategoryInfo info = arg as CategoryInfo;
            if (info == null)
                return string.Empty;

            return this.siteUrls["productCategoryShow"].BuilderUrl(info.Id);
        }

        public string ProductCategorySearch(object arg)
        {
            CategoryInfo category = arg as CategoryInfo;
            if (category == null)
                return string.Empty;

            return ProductCategorySearch(category.Id);
        }
        public string ProductCategorySearch(int categoryId)
        {
            return this.siteUrls["productCategories"].BuilderUrl(categoryId);
        }

        public string ProductEdit(int id, int baseNodeId)
        {
            return this.siteUrls["admin_ProductEdit"].BuilderUrl(baseNodeId, id);
        }

        public string ProductFiles(int productId)
        {
            return this.siteUrls["admin_ProductFileList"].BuilderUrl(productId);
        }

        public string ProductShow(object obj)
        {
            ProductInfo info = obj as ProductInfo;
            if (info == null)
                return string.Empty;

            return ProductShow(info.ProductCategoryId, info.Id);
        }
        public string ProductShow(int categoryId, int id)
        {
            return ProductShow(categoryId, id,0);
        }
        public string ProductShow(int categoryId, int id, int currencyId)
        {
            ProductInfo product = Products.GetProduct(id);

            return this.siteUrls["productShow"].BuilderUrl(
                categoryId,
                id,
                currencyId,
                product == null ? "ProductShow" : this.UrlEncode(product.Title));
        }

        public string ProductSearch(object obj)
        {
            CategoryInfo info = obj as CategoryInfo;
            if (info == null)
                return string.Empty;

            return ProductSearch(info.Id, string.Empty);
        }
        public string ProductSearch(int categoryId, string searchKey)
        {
            int baseNodeId = SiteContext.Current.BaseNodeId;
            if (baseNodeId <= 0)
            {
                CategoryInfo category=TreeTables.ProductCategories.GetBaseNode(categoryId);
                if (category != null)
                    baseNodeId = category.Id;
                else
                    baseNodeId = 0;
            }

            return ProductSearch(baseNodeId, categoryId, searchKey, new Pair<Decimal?>(null, null),null,string.Empty,null);
        }
        public string ProductSearch(int baseNodeId, int categoryId, string searchKey, Pair<Decimal?> priceRange,Boolean? isWholesale,string orderBy,int? pageSize)
        {
            CategoryInfo category = TreeTables.ProductCategories.GetModelById(categoryId);

            string parameters = string.Format(
                "{0}-{1}-{2}",
                isWholesale == null ? string.Empty : isWholesale.ToString(),
                orderBy,
                pageSize == null ? string.Empty : pageSize.ToString());

            return
                this.siteUrls["products"].BuilderUrl(
                baseNodeId,
                categoryId,
                searchKey,
                priceRange.Left == null ? string.Empty : ((Decimal)priceRange.Left).ToString(),
                priceRange.Right == null ? string.Empty : ((Decimal)priceRange.Right).ToString(),
                parameters,
                this.UrlEncode(category == null ? "Products" : category.Title));
        }

        public string ProductSearchAdmin(bool enableDelBtn, bool enableTopBtn, bool enableHotBtn, int baseNodeId, StatusType type ,int categoryId,string searchKey)
        {
            return this.siteUrls["admin_ProductList"].BuilderUrl(enableDelBtn, enableTopBtn, enableHotBtn, baseNodeId, (int)type,categoryId,searchKey);
        }

        public string Commentaries(int productId)
        {
            return this.siteUrls["admin_ProductCommentaryList"].BuilderUrl(productId);
        }

        public string CommentaryEdit(int id, int productId)
        {
            return this.siteUrls["admin_ProductCommentaryEdit"].BuilderUrl(id, productId);
        }
        #endregion

        #region Currency

        public string CurrencyEdit(int id)
        {
            return this.siteUrls["admin_CurrencyEdit"].BuilderUrl(id);
        }

        #endregion

        #region WholesaleRule

        public string WholesaleRuleEdit(int id)
        {
            return this.siteUrls["admin_ProductWholesaleRuleEdit"].BuilderUrl(id);
        }

        #endregion

        #region ProductStorage

        public string ProductStorageEdit(int id)
        {
            return this.siteUrls["admin_StorageEdit"].BuilderUrl(id);
        }

        public string ProductStorageSearch(bool enableDelBtn, bool enableTopBtn, bool enableHotBtn, string model, string productName, string brandName)
        {
            return this.siteUrls["admin_StorageList"].BuilderUrl(
                enableDelBtn, 
                enableTopBtn, 
                enableHotBtn, 
                SiteUrls.BuilderStorageSearchKey(model, productName, brandName));
        }
        public string ProductStorageSearch(string model, string productName, string brandName)
        {
            return this.siteUrls["productStorages"].BuilderUrl(SiteUrls.BuilderStorageSearchKey(model,productName,brandName));
        }

        private static string BuilderStorageSearchKey(string model, string productName, string brandName)
        {
            return string.Format("{0}|{1}|{2}", model, productName, brandName);
        }
        public static string[] AnalyzeStorageSearchKey(string searchKeys)
        {
            if (!string.IsNullOrEmpty(searchKeys))
            {
                string[] searchGroup = searchKeys.Split('|');

                if (searchGroup.Length == 3)
                    return searchGroup;
            }

            return new string[] { string.Empty, string.Empty, string.Empty }; ;
        }


        #endregion

        #region Logistics

        public string LogisticsCompanyEdit(int id)
        {
            return this.siteUrls["admin_LogisticsEdit"].BuilderUrl(id);
        }

        public string LogisticsExpressionsEdit(int cityId)
        {
            return this.siteUrls["admin_LogisticsExpressionsEdit"].BuilderUrl(cityId);
        }

        #endregion

        #region UpFile

        public string UpFileEdit(int itemId, int id)
        {
            return this.siteUrls["admin_UpFileEdit"].BuilderUrl(itemId, id);
        }

        #endregion

        #region Subscribe

        public string SubscribeShow(int id)
        {
            return this.siteUrls["admin_SubscribeShow"].BuilderUrl(id);
        }

        #endregion

        #region GuestBook

        public string GuestBook()
        {
            return this.siteUrls["guestBook"].ToString();
        }

        public string GuestBookShow(int id)
        {
            return this.siteUrls["admin_GuestBookShow"].BuilderUrl(id);
        }

        public string GuestBookSearch(GuestBookItem itemType,bool? isRead)
        {
            return this.siteUrls["admin_GuestBookList"].BuilderUrl(isRead.As<string>(), (int)itemType);
        }

        #endregion

        #region Message

        public string MessageShow(int id)
        {
            return this.siteUrls["admin_MessageShow"].BuilderUrl(id);
        }

        #endregion

        #region Link

        public string LinkEdit(int Id)
        {
            int baseNodeId = SiteContext.Current.BaseNodeId;
            if (baseNodeId <= 0)
                baseNodeId = 0;

            return this.siteUrls["admin_LinkEdit"].BuilderUrl(baseNodeId,Id);
        }

        public string LinkSearch(object obj)
        {
            CategoryInfo category = obj as CategoryInfo;
            if (category == null)
                return string.Empty;

            int baseNodeId = TreeTables.LinkCategories.GetBaseNode(category.Id).Id;

            return LinkSearch(baseNodeId, category.Id);
        }
        public string LinkSearch(int baseNodeId,int categoryId)
        {
            return this.siteUrls["links"].BuilderUrl(baseNodeId, categoryId);
        }

        public string LinkAminSearch(int itemId, string searchKey)
        {
            return this.siteUrls["admin_LinkManage"].BuilderUrl(SiteContext.Current.BaseNodeId,itemId, searchKey);
        }

        public string LinkShow(object obj)
        {
            LinkInfo link = obj as LinkInfo;

            return link.Url;
        }
        
        #endregion

        #region Download

        public string DownloadSearch(object obj)
        {
            CategoryInfo category = obj as CategoryInfo;
            if (category == null)
                return string.Empty;

            int baseNodeId = TreeTables.UpFileCategories.GetBaseNode(category.Id).Id;

            return this.siteUrls["download"].BuilderUrl(baseNodeId, category.Id, string.Empty);
        }

        public string DownloadSearch(int baseNodeId, int categoryId, string searchKey)
        {
            return this.siteUrls["download"].BuilderUrl(baseNodeId, categoryId, searchKey);
        }

        #endregion

        #region other

        public string My97DatePicker
        {
            get { return this.siteUrls["my97DatePicker"].ToString(); }
        }

        #endregion

        #region order

        public string Cart()
        {
            return Cart(CartActionType.None, 0, 0);
        }
        public string Cart(CartActionType type, int productId, int Quantity)
        {
            return this.siteUrls["myCart"].BuilderUrl((int)type, productId, Quantity);
        }

        public string OrderAdd()
        {
            return this.siteUrls["orderAdd"].ToString();
        }
        public string Order(int orderId)
        {
            return this.siteUrls["order"].BuilderUrl(orderId.ToString());
        }

        public string OrderEnd(int orderId)
        {
            return this.siteUrls["orderEnd"].BuilderUrl(orderId.ToString());
        }

        public string OrderPayment(int orderId)
        {
            return this.siteUrls["payment"].BuilderUrl(orderId);
        }
        public string OrderWesternUnion(int orderId)
        {
            return this.siteUrls["westernUnion"].BuilderUrl(orderId);
        }
        public string OrderBankTransfer(int orderId)
        {
            return this.siteUrls["bankTransfer"].BuilderUrl(orderId);
        }

        public string OrderShow(int orderId)
        {
            if (SiteContext.Current.User.IsAdmin && SiteContext.Current.MapNode != null && SiteContext.Current.MapNode.Type == MapType.AdminMenu)
                return this.siteUrls["admin_OrderShow"].BuilderUrl(orderId);

            return this.siteUrls["order"].BuilderUrl(orderId);
        }

        public string OrderLogistics(int orderId)
        {
            return this.siteUrls["admin_OrderLogistics"].BuilderUrl(orderId);
        }

        #endregion

        public string SinglePage(SinglePage pageType)
        {
            return this.siteUrls["singlePage"].BuilderUrl((int)pageType);
        }

        private string UrlEncode(string str)
        {
            System.Text.RegularExpressions.Regex regex=new System.Text.RegularExpressions.Regex(@"[^\w]");

            return regex.Replace(str,"-");
        }

    }
}
